﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Diagnostics;

namespace FBNotifier
{
    public enum FacebookEventTypes { Message, Notification };

    public struct FacebookEvent
    {
        public FacebookEventTypes eventType;
        public string subject;
        public string body;
        public string photoUrl;
        public string authorName;
        public string timeReceived;
        public string url;
    };

    public static class NewEventsSystem
    {
        private static AutoResetEvent eventPushedInQueue = new AutoResetEvent(false);
        private static Queue<FacebookEvent> queue = new Queue<FacebookEvent>();

        static NewEventsSystem()
        {
            Thread workerThread = new Thread(DoWork);
            workerThread.IsBackground = true;
            workerThread.Start();
        }

        public static void PushNewEvents(List<FacebookMessage> newMessages, List<FacebookNotification> newNotifications)
        {
            foreach (FacebookMessage message in newMessages)
            {
                FacebookEvent newEvent;
                newEvent.eventType = FacebookEventTypes.Message;
                newEvent.subject = message.subject;
                newEvent.body = message.snippet;
                newEvent.authorName = message.snippetAuthorName;
                newEvent.photoUrl = String.Format("http://graph.facebook.com/{0}/picture", message.snippetAuthorId);
                newEvent.timeReceived = message.updatedTime;
                newEvent.url = String.Format("http://www.facebook.com/?sk=messages&tid={0}", message.threadId);

                queue.Enqueue(newEvent);
            }

            foreach (FacebookNotification notification in newNotifications)
            {
                FacebookEvent newEvent;
                newEvent.eventType = FacebookEventTypes.Notification;
                newEvent.subject = notification.titleText;
                newEvent.body = notification.bodyText;
                newEvent.photoUrl = String.Format("http://graph.facebook.com/{0}/picture", notification.senderId);
                newEvent.authorName = "";
                newEvent.timeReceived = notification.createdTime;
                newEvent.url = notification.url;

                queue.Enqueue(newEvent);
            }

            if (newMessages.Count + newNotifications.Count > 0)
            {
                if ((Application.Current as App).PlaySounds)
                {
                    WinMMWrapper.PlayWavResource("pack://application:,,,/Sounds/notificationsound.wav");
                }

                eventPushedInQueue.Set();
            }
        }

        public static bool PopEvent(ref FacebookEvent fbEvent)
        {
            if (queue.Count > 0)
            {
                fbEvent = queue.Dequeue();

                return true;
            }
            else
            {
                return false;
            }
        }
        
        private static void DoWork()
        {
            //http://eprystupa.wordpress.com/2008/07/28/running-wpf-application-with-multiple-ui-threads/
            do
            {
                eventPushedInQueue.WaitOne();

                Debug.WriteLine("there is a new event in the queue. NotifierWindowOpened = " + FBAlertWindow.NotifierWindowOpened.ToString());

                if (!FBAlertWindow.NotifierWindowOpened)
                {
                    Thread thread = new Thread(() =>
                    {
                        Debug.WriteLine("opening a new notifier window");

                        FBAlertWindow w = new FBAlertWindow();

                        w.Closed += delegate(object s2, EventArgs e2)
                        {
                            w.Dispatcher.InvokeShutdown();
                            FBAlertWindow.NotifierWindowOpened = false;
                        };

                        System.Windows.Threading.Dispatcher.Run();
                    });

                    thread.SetApartmentState(ApartmentState.STA);
                    thread.IsBackground = true;
                    thread.Start();
                }

            } while (true);
        }
    }
}
